home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
tex
/
wp2x110.zip
/
WP2X.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-18
|
53KB
|
1,516 lines
/* $Id: wp2x.c 1.10 91/08/18 15:05:41 raymond Exp $ */
/* Before compiling, read the section titled `portability concerns'. */
/************************************************************************
* $Log: wp2x.c $
* Revision 1.10 91/08/18 15:05:41 raymond
* Descriptor file stuff.
*
* Revision 1.9 91/08/06 09:08:09 raymond
* add missing `break' in check_arity
*
* Revision 1.8 91/08/06 08:31:21 raymond
* Avoid infinite loop if file is corrupted.
* Better error-checking on configuration file (new output scheme).
*
* Revision 1.7 91/08/02 13:35:37 raymond
* Epsilonically better handling of environments that didn't end properly.
* Change return type of main() to keep gcc quiet.
* MSC support.
*
* Revision 1.6 91/07/28 21:08:53 raymond
* BeginTabs et al, FNote#, ENote#, NegateTotal, more unsupported codes
* Improve character tokens, Header, Footer
* Take care when people don't end lines with HRt
* Fix major bugs in endnote processing, footnote numbering (and nobody
* noticed!)
* More worries about signed characters.
*
* Revision 1.5 91/07/23 22:59:43 raymond
* Add COMMENT token, and some bug fixes.
*
* Revision 1.4 91/07/23 22:09:23 raymond
* Concessions to slightly non-ANSI compilers. (`const', `unsigned char')
* More patches for machines with signed characters.
* Fix blatant bug in hex constants. (Amazed nobody noticed.)
* New tags SetFn#, Header, Footer.
* Warning messages for unsupported tokens.
* Backslahes processed in character tags.
* Fixed(?) footnotes, endnotes, page length changes.
* Inserted missing `break's into the huge switch.
*
* Revision 1.3 91/07/12 15:39:44 raymond
* Spiffy Turbo C support.
* Some <stdlib.h>'s don't declare errno et al.
* Command line switches `-s' and `-n' added.
* More cute warning messages.
* Dots periodically emitted.
* Give the enum of token types a name, to placate QuickC.
* Fix problems with pitch changes and signed characters.
*
* Revision 1.2 91/06/22 08:18:22 raymond
* <process.h> and fputchar() aren't sufficiently portable.
* strerror() fails to exist on some so-called ANSI platforms.
* Removed assumption that characters are unsigned.
* Forgot to #include <stdarg.h>
*
*/
/************************************************************************
* PORTABILITY CONCERNS
************************************************************************
*
* If possible, compile with unsigned characters. (Though I think
* I've taken care of all the places where I assumed characters are
* unsigned.)
*
* This program assumes that your compiler is fully ANSI-conformant.
* Depending on how non-conformant your compiler is, you may need to
* set the following symbols at compile time:
*
* NO_CONST -- set this if your compiler does not know what `const' means.
* Cdecl -- how to tag functions that are variadic.
*
* Cdecl is used if you need special declarations for variadic functions.
* This is used by IBM PC compilers so that you can make the default
* parameter passing Pascal-style or Fastcalls.
*
* Some very machine-dependent stuff happens when trying to open the
* descriptor file. Please read dopen.c as well.
*/
#ifdef NO_CONST
#define const
#endif
#ifndef Cdecl /* default is nothing */
#define Cdecl
#endif
/************************************************************************
* This program divides naturally into two parts.
*
* The first part reads in the descriptor file and builds the expansions
* for each of the identifiers listed above.
* This is the easy part.
*
* The second part reads the input file and uses the expansions collected
* in the first part to transform the file into the output.
* This is the hard part.
*
************************************************************************/
/* And now, the code.
* We start off with some obvious header files.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* Some platforms do not define these externals in stdlib.h */
extern int Cdecl errno;
extern char *Cdecl sys_errlist[];
extern int Cdecl sys_nerr;
/************************************************************************/
/* Some common idioms */
/************************************************************************/
#define do_nothing /* twiddle thumbs */
/************************************************************************/
/* Blowing up */
/************************************************************************/
/* The function "error" accepts two arguments. A FILE pointer and
* a printf-style argument list. The printf-style arguments are
* printed to stderr. If the FILE is non-NULL, the the remaining
* contents of the file are printed as well (to provide context), up
* to 80 characters.
*/
void Cdecl error(FILE *fp, char *fmt, ...)
{
int i;
va_list ap;
fputs("Error: ", stderr);
va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap);
fputc('\n', stderr);
if (fp) {
fprintf(stderr, "Unread text: ");
for (i = 0; i < 80 && !feof(fp); i++) fputc(getc(fp), stderr);
fputc('\n', stderr);
}
exit(1);
}
/************************************************************************/
/* Command-line switches */
/************************************************************************/
int silent = 0;
int blipinterval = 1024; /* display blips every 1K */
int blipcount;
/************************************************************************/
/* Basic file manipulations */
/************************************************************************/
/* We here define a few basic functions. Let us hope that the first
* three functions' names are self-descriptive.
*/
int next_non_whitespace(FILE *fp)
{
register int c;
while ((c = getc(fp)) != EOF && isspace(c)) do_nothing;
return c;
}
int next_non_space_or_tab(FILE *fp)
{
register int c;
while ((c = getc(fp)) != EOF && (c == ' ' || c == '\t')) do_nothing;
return c;
}
void eat_until_newline(FILE *fp)
{
register int c;
while ((c = getc(fp)) != EOF && c != '\n') do_nothing;
}
/* The function parse_hex grabs a (no-more-than-two-character) hex
* constant. Similarly, parse_octal does the same for octal constants.
*/
int parse_hex(FILE *fp)
{
register int c, value;
if (!isxdigit(c = toupper(getc(fp))))
error(fp, "Expecting a hex digit");
if ((value = c - '0') > 9) value += '0' - 'A' + 10;
if (!isxdigit(c = getc(fp))) { ungetc(c, fp); return value; }
c = toupper(c);
value = (value << 4) + c - '0';
if (c > '9') value += '0' - 'A' + 10;
return value;
}
int parse_octal(FILE *fp, register int c)
{
register int value = c - '0';
if ( (c = getc(fp)) < '0' || c > '7') { ungetc(c, fp); return value; }
value = (value << 3) + c - '0';
if ( (c = getc(fp)) < '0' || c > '7') { ungetc(c, fp); return value; }
return (value << 3) + c - '0';
}
/************************************************************************/
/* Storing the input strings */
/************************************************************************/
/* The input strings are allocated from a large pool we set up at
* startup. This lets us do our thing without having to fight
* with people like malloc and friends. This method does limit
* our configuration file to 32K, however. We hope that this is
* not a problem. (It also means that the program can be translated
* to almost any other language without too much difficulty.)
*
* Here's how it works.
*
* "pool" is an array of POOL_SIZE characters. The value of POOL_SIZE
* is flexible, but shouldn't exceed 65535, since that's the size o